/*
 * MediaPlayer.cpp
 *
 *  Created on: 2018年8月2日
 *      Author: zhengboyuan
 */
#include "stdafx.h"
#include "MediaPlayer.h"
#include "CLog.h"

MediaPlayer::MediaPlayer():
    m_handle(),
    m_sink(),
	m_hwnd(),
	m_msgWnd(),
	m_msg(),
	m_videoFrameCount(),
	m_id()
{
    m_handle = MDecode_CreateHandle();
}

MediaPlayer::~MediaPlayer()
{
    MDecode_DestroyHandle(m_handle);
}

bool MediaPlayer::isDecoderOpen()
{
    return (m_handle != NULL);
}

bool MediaPlayer::Snap(const char* filepath)
{
    BOOL ret = MDecode_Snap(m_handle, filepath);
    return (ret > 0);
}


/// 设置显示比例
bool MediaPlayer::SetRatio(int cx, int cy)
{
    BOOL ret = MDecode_SetRatio(m_handle, cx, cy);
    return (ret > 0);
}

/// 打开声音
bool MediaPlayer::OpenSound()
{
    BOOL ret = MDecode_OpenSound(m_handle);
    return (ret > 0);
}

/// 关闭声音
bool MediaPlayer::CloseSound()
{
    BOOL ret = MDecode_CloseSound(m_handle);
    return (ret > 0);
}

bool MediaPlayer::IsSoundOpen()
{
	BOOL ret = MDecode_IsSoundOpen(m_handle);
	return (ret > 0);
}

bool MediaPlayer::ToggleSound()
{
	if (IsSoundOpen())
	{
		return CloseSound();
	}
	return OpenSound();
}

/// 设置音量
bool MediaPlayer::SetVolume(int volume)
{
    BOOL ret = MDecode_SetVolume(m_handle, volume);
    return (ret > 0);
}

/// 获取音量
int MediaPlayer::GetVolume()
{
    int volume = 0;
    MDecode_GetVolume(m_handle, &volume);
    return volume ;
}

bool MediaPlayer::Seek(int64_t pts)
{
	BOOL ret = MDecode_Seek(m_handle, pts);
	return (ret > 0);
}

bool MediaPlayer::CanSeek()
{
	double duration = 0;
	MDecode_GetDuration(m_handle, &duration);
    return (duration > 0);
}

bool MediaPlayer::SetScale(double scale)
{
	BOOL ret = MDecode_SetScale(m_handle, scale);
    return (ret == TRUE);
}

int64_t MediaPlayer::GetDuration()
{
	double duration = 0;
	MDecode_GetDuration(m_handle, &duration);
    return (int64_t)(duration * 1000);
}

int64_t MediaPlayer::GetTime()
{
	int64_t pts = 0;
	MDecode_GetTime(m_handle, &pts);
    return pts;
}

bool MediaPlayer::Play()
{
	BOOL ret = MDecode_Play(m_handle);
	return (ret > 0);
}

bool MediaPlayer::Pause(bool toPause)
{
	BOOL ret = MDecode_Pause(m_handle, toPause);
    return (ret > 0);
}

void MediaPlayer::SetSink(MediaPlayerSink* sink)
{
    m_sink = sink;
}

void MediaPlayer::onEndOfStream(int reason)
{
    if (m_sink)
    {
        m_sink->onEndOfStream(this, reason);
    }
}

bool MediaPlayer::GetPictureSize(int& width, int& height)
{
    BOOL ret = MDecode_GetPictureSize(m_handle, &width, &height);
    return (ret > 0);
}

void MediaPlayer::EnableDrawTrack(bool enabled)
{
    // pass
}

void MediaPlayer::SetVideoWnd(HWND hwnd)
{
	m_hwnd = hwnd;

	if (IsOpen())
	{
		MDecode_SetVideoWnd(m_handle, m_hwnd);
	}
}

void MediaPlayer::SetWndMsg(HWND hwnd, UINT msg)
{
	m_msgWnd = hwnd;
	m_msg = msg;
}

void MediaPlayer::onOpen()
{
	if (::IsWindow(m_hwnd))
	{
		MDecode_SetVideoWnd(m_handle, m_hwnd);
	}

	MDecode_SetEventCallback(m_handle, eventCallback, this);
	
	MDecode_SetDecodeCallback(m_handle, MDECODE_PIXEL_NONE, decodeCallback, this);
}

void MediaPlayer::eventCallback(HANDLE handle, int event, const char* value, int size, void* pUser)
{
	MediaPlayer* pthis = (MediaPlayer*)pUser;
	if (pthis)
	{
		pthis->eventCallback(event, value, size);
	}
}

void MediaPlayer::eventCallback(int event, const char* value, int size)
{
	CLog::info("MediaPlayer::eventCallback(%d). event: %d\n", m_id, event);

	if (event == MDECODE_EVENT_END)
	{
		onEndOfStream(true);
	}
	else if (event == MDECODE_EVENT_STOPPED)
	{
		onEndOfStream(false);
	}
	else
	{
		if (m_sink)
		{
			m_sink->onPlayerEvent(this, event, value, size);
		}
	}
}

bool MediaPlayer::startRecord(const char* filepath)
{
	BOOL ret = MDecode_StartRecord(m_handle, filepath);
	return (ret > 0);
}

void MediaPlayer::stopRecord()
{
	MDecode_StopRecord(m_handle);
}

bool MediaPlayer::isRecording()
{
	BOOL ret = MDecode_IsRecording(m_handle);
	return (ret > 0);
}

void MediaPlayer::InputFaceTrack(const char* devID, const char* text, int size)
{
	return;
}

HANDLE MediaPlayer::GetHandle()
{
	return m_handle;
}

void MediaPlayer::SetDelayTime(int ms)
{
	MDecode_SetDelayTime(m_handle, ms);
}

bool MediaPlayer::IsFullscreen()
{
	return MDecode_IsFullscreen(m_handle) == TRUE;
}

void MediaPlayer::SetFullscreen(bool isFull)
{
	MDecode_SetFullscreen(m_handle, isFull);
}

void MediaPlayer::EnableDrawGraph(int mode)
{
	MDecode_EnableDrawGraph(m_handle, mode);
}

void MediaPlayer::SetDrawGraph(const char* text, int size)
{
	MDecode_SetDrawGraph(m_handle, text, size);
}

const char* MediaPlayer::GetDrawGraph()
{
	return MDecode_GetDrawGraph(m_handle);
}

void MediaPlayer::RemoveDrawGraph(LONG mode)
{
	MDecode_RemoveDrawGraph(m_handle, mode);
}

void MediaPlayer::decodeCallback(HANDLE handle, MDecode_Frame* frame, void* pUser)
{
	MediaPlayer* pthis = (MediaPlayer*)pUser;
	if (pthis)
	{
		pthis->decodeCallback(frame);
	}
}

void MediaPlayer::decodeCallback(MDecode_Frame* frame)
{
	if (frame->type == MDECODE_MEDIA_VIDEO)
	{
		m_videoFrameCount ++;

		if (m_videoFrameCount == 1)
		{
			CLog::info("MediaPlayer::decodeCallback(%d). first video frame.\n", m_id);

			if (m_sink)
			{
				m_sink->onPlayerEvent(this, MDECODE_EVENT_FIRST_VIDEO_FRAME, (char*)&m_videoFrameCount, sizeof(m_videoFrameCount));
			}
		}
	}
}

void MediaPlayer::setID(size_t id)
{
	m_id = id;
}

size_t MediaPlayer::getID()
{
	return m_id;
}